package qiyu.live.im.router.provider.cluster;

import cn.hutool.core.util.StrUtil;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.cluster.LoadBalance;
import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sfx
 * Date: 2023-10-12
 * Time: 20:32
 */
public class IMRouterClusterInvoker<T> extends AbstractClusterInvoker<T> {

    private Logger logger = LoggerFactory.getLogger(IMRouterClusterInvoker.class);

    public IMRouterClusterInvoker(Directory<T> directory) {
        super(directory);
    }

    @Override
    protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
        checkWhetherDestroyed();
        String ip = (String) RpcContext.getContext().get("ip");
        if (StrUtil.isEmpty(ip)) {
            throw new RuntimeException("ip can not be null!");
        }
        // 得到我们调用的RPC服务中的所有服务提供者,找到与该ip相同的ip的invoker进行返回
        List<Invoker<T>> invokerList = list(invocation);
        Invoker<T> tInvoker1 = invokerList.stream().filter(tInvoker -> {
            String invokerIp = tInvoker.getUrl().getHost() + ":" + tInvoker.getUrl().getPort();
            return invokerIp.equals(ip);
        }).findFirst().orElse(null);

        if (tInvoker1 == null) {
            logger.error("not find invoker ip is not valid");
            throw new RuntimeException("not find invoker ip is not valid");
        }
        return tInvoker1.invoke(invocation);
    }
}